package eos.dom.server;

import java.util.Vector;

import javax.jdo.annotations.Element;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.appengine.api.datastore.Key;

@PersistenceCapable
public class Player {

	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	private Key key;
	@Persistent
	@Element(dependent="true")
	private Deck deck;
	@Persistent
	@Element(dependent="true")
	private Discard discard;
	@Persistent
	@Element(dependent="true")
	private Hand hand;
	@Persistent
	private String client;
	@Persistent
	private Integer actionCount = 0;
	@Persistent
	private Integer buyCount = 0;
	@Persistent
	private Integer GoldCount = 0;
	@Persistent
	private Integer tempGoldCount = 0;
	@Persistent
	private Integer nCardsToDiscard = 0;
	@Persistent
	private Integer nCardsToDiscardOrCurse = 0;
	@Persistent
	private Boolean masquerade = false;


	public Player(String name){
		client = name;
		discard = new Discard();
		deck = new Deck();
		hand = new Hand();
		drawNCards(5);
		nCardsToDiscard = 0;
		nCardsToDiscardOrCurse = 0;
		masquerade = false;
	}

	public int getVictoryPoints(){
		int v = 0; 
		if(!hand.isEmpty()){
			for(Integer c: hand.getHandCards()){
				v += new Card(CardId.class.getEnumConstants()[c]).getPoints();
			}
		}
		if(!deck.isEmpty()){
			for(Integer c:deck.getCards()){
				v += new Card(CardId.class.getEnumConstants()[c]).getPoints();
			}
		}
		if(!discard.isEmpty()){
			for(Integer c:discard.getCards()){
				v+= new Card(CardId.class.getEnumConstants()[c]).getPoints();
			}
		}
		return v;
	}

	public java.util.Stack<Integer> getDeck() {
		return deck.getCards();
	}

	public java.util.Stack<Integer> getDiscard() {
		return discard.getCards();
	}

	public Vector<Integer> getHand() {
		return hand.getHandCards();
	}

	public boolean hasCardInHand(CardId c) {
		for(Integer card:hand.getHandCards()){
			if(card ==c.ordinal()){
				return true;
			}
		}
		return false;
	}

	public void removeCardFromHand(CardId id) {
		//test if player has card
		for(int i = 0;i<hand.size();i++){
			if (hand.get(i) == id.ordinal()){
				hand.remove(i);
			}
		}
	}

	public void getACard(CardId id) {
		discard.push(id.ordinal());
	}

	public void getACardInHand(CardId id2) {
		hand.add(id2.ordinal());
	}

	public void drawNCards(int n) {
		for(int i = 0;i<n;i++){
			//Cas ou le deck manque de carte
			if(deck.isEmpty()){
				shuffleDiscardIntoNewDeck();
				hand.add(deck.pop());
			}else{
				hand.add(deck.pop());
			}
		}
	}

	private void shuffleDiscardIntoNewDeck() {
		deck.pushAll(discard.getCards());
		discard.clear();
		deck.shuffle();
	}

	public void discardNCards(int n) {

		//POPUP POUR LE CHOIX A FAIRE
	}

	public void discardAll() {
		while(!hand.isEmpty()){
			discard.push(hand.remove(0));
		}
	}

	public void discardDeck(){

	}

	public String getClient() {
		return client;
	}

	@Override
	public String toString() {
		return client;
	}

	public String moreInfo() {
		return "hand "+hand.getHandCards()+"\n deck "+deck.getCards();
	}

	public void addAction(int n){
		actionCount += n;
	}
	public boolean useAction(){
		if(actionCount>0){
			actionCount--;
			return true;
		}else{
			return false;
		}
	}
	public boolean useBuy(){
		if(buyCount>0){
			buyCount--;
			return true;
		}else{
			return false;
		}
	}
	public void addBuy(int n){
		buyCount += n;
	}
	public boolean useGold(int cost){
		if(cost<= (tempGoldCount+GoldCount)){
			tempGoldCount = tempGoldCount - cost;
			if(tempGoldCount < 0){
				cost = cost - tempGoldCount;
				GoldCount = GoldCount - cost;
			}
			return true;
		}else{
			return false;
		}
	}
	public void addTempGold(int n){
		tempGoldCount += n;
	}
	public void setGold(int g){
		GoldCount = g;
	}

	public void setnCardsToDiscard(Integer nCardsToDiscard) {
		this.nCardsToDiscard = nCardsToDiscard;
	}

	public Integer getnCardsToDiscard() {
		return nCardsToDiscard;
	}

	public void setnCardsToDiscardOrCurse(Integer nCardsToDiscardOrCurse) {
		this.nCardsToDiscardOrCurse = nCardsToDiscardOrCurse;
	}

	public Integer getnCardsToDiscardOrCurse() {
		return nCardsToDiscardOrCurse;
	}

	public void setMasquerade(Boolean masquerade) {
		this.masquerade = masquerade;
	}

	public Boolean getMasquerade() {
		return masquerade;
	}
	
}
